from pathlib import Path
from fastapi import UploadFile
import os
import mimetypes

UPLOAD_DIR = "./file"  # 假设 files 目录位于项目根目录下
os.makedirs(UPLOAD_DIR, exist_ok=True)

from core.config import settings
from core.llm import get_embedding_llm, get_default_llm
from pymilvus import MilvusClient
from langchain_community.document_loaders import Docx2txtLoader, TextLoader, PyPDFLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
import logging

logger = logging.getLogger(__name__)

class FileService:
    def __init__(self):
        self.milvus_client = MilvusClient(settings.MILVUS_URL)
        self.llm = get_embedding_llm()
        self.chat_llm = get_default_llm()

    def load_file(self, file: UploadFile):
        try:
            # 立即读取文件内容，避免延迟访问
            contents = file.file.read()
            file_location = os.path.join(UPLOAD_DIR, file.filename)
            
            # 保存文件
            with open(file_location, "wb") as f:
                f.write(contents)
            
            # 根据文件类型选择不同的加载器
            file_type = file.content_type or mimetypes.guess_type(file.filename)[0]
            
            if file_type == "text/plain" or file.filename.endswith('.txt'):
                loader = TextLoader(file_location, encoding='utf-8')
            elif file_type == "application/pdf" or file.filename.endswith('.pdf'):
                loader = PyPDFLoader(file_location)
            elif file_type in ["application/vnd.openxmlformats-officedocument.wordprocessingml.document", 
                              "application/msword"] or file.filename.endswith(('.docx', '.doc')):
                loader = Docx2txtLoader(file_location)
            elif file_type in ["text/markdown", "text/x-markdown"] or file.filename.endswith('.md'):
                loader = TextLoader(file_location, encoding='utf-8')
            else:
                # 默认按文本处理
                loader = TextLoader(file_location, encoding='utf-8')
            
            data = loader.load()
            return data
        except Exception as e:
            logger.error(f"文件加载失败: {e}")
            raise RuntimeError(f"Error reading or writing file: {e}")

    def split_file(self, data):
        spliter = RecursiveCharacterTextSplitter(
            chunk_size=800,  # 建议适当减小，便于嵌入模型处理
            chunk_overlap=100,  # 增加重叠部分，保留上下文语义
            length_function=len,
            separators=[
                "\n\n",  # 优先按段落分隔
                "\n",  # 其次按换行分隔
                "。", "！", "?", "？", "!",
                " ",
                " ",  # 英文空格
                "",  # 最后兜底按字符切分
            ]
        )
        chunks = spliter.split_documents(data)
        return chunks

    def embedding(self, chunk):
        try:
            embeds = self.llm.embed_query(chunk.page_content)
            return embeds
        except Exception as e:
            logger.error(f"Embedding失败: {e}")
            return None

    def insert_to_milvus(self, data):
        try:
            self.milvus_client.insert("teach_platform", data)
        except Exception as e:
            logger.error(f"插入Milvus失败: {e}")
            # 不抛出异常，避免阻塞上传流程






    


